# @Time   : 2022/1/18 15:00
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^

"""
二拼板的算法,主要包括首板尺寸确认,两拼板的识别问题,获取切线的函数
"""
import time

import os
from db_tools.db_handler import DbHandler
from vision_process.image_process_common import *

db = DbHandler()
cp = ConfigParams()

calcArgsNormal = {
    "1": [[2], 17, 11, 8, 18, [20, 40, 60, 120, 150], 0.2],
    "2": [[2], 17, 17, 8, 15, [5, 10, 20, 40], 0],
    "3": [[0], 17, 17, 8, 15, [3, 5, 10, 20, 40, 55], 0],
    "4": [[11], 17, 17, 8, 20, [1, 2, 5, 10, 15], 0],
    "5": [[10], 17, 15, 8, 20, [1, 2, 5], 0],
    # "6": [[1], 17, 17, 8, 15, [20, 40, 60, 80], 0.1] ,
}
tryBeginIndex = 1
upDownSlice = int(50 * cp.mm2pix)
jointLineExtend = 23  # 单位pix
innerToEdgeThres = 6  # 单位mm
minLineLength = int(20 * cp.mm2pix)  # 线条最短是多少,50个mm
lineLengthMin = 20 * cp.mm2pix
maxLineGap = 5


def check_inner_board_2p(board, width, height, calcThresBig, calcThresSmall, boardColor, boardPos, upBox, heightHalf, innerLine, extendMiddle,
                         isFirstCheck, offset, totalBoard):
    """
    两拼板检测内板找到的内板信息
    :param board:填充后的内板
    :param width:内板的宽
    :param height:内板的高
    :param calcThresBig:识别的偏大阈值
    :param calcThresSmall:识别的偏小阈值
    :param boardColor:原图的三通道图片
    :param boardPos:检测的板的位置,是上框还是下框
    :param upBox:上框的位置信息,检测是否叠板的时候使用
    :param heightHalf:整个物料的高度的一半
    :param innerLine:是否从内往外面找线
    :param extendMiddle:是否延长中缝
    :param isFirstCheck:是否是首板
    :param offset:首板的位置信息
    :return:
    """
    global minLineLength, maxLineGap, lineLengthMin
    boardArea = width * height
    totalHeightPix, totalWidthPix = board.shape[:2]
    totalWidthMm, totalHeightMm = round(totalWidthPix / cp.mm2pix, 2), round(totalHeightPix / cp.mm2pix, 2)
    moveWidth13 = int(totalWidthPix * 0.21)
    moveWidthMid = int(totalWidthPix * 0.3)
    moveHeight = int(totalHeightPix * 0.25)

    res = {
        "result": "error",
        "box": None,
        "info": "",
        "calcSize": (totalWidthMm, totalHeightMm),
        "calcError": (0, 0)
    }
    widthMax = width / cp.mm2pix + calcThresBig
    widthMin = width / cp.mm2pix - calcThresSmall
    heightMax = height / cp.mm2pix + calcThresBig
    heightMin = height / cp.mm2pix - calcThresSmall
    widthMm = width / cp.mm2pix
    heightMm = height / cp.mm2pix
    moveAngleUsed = board.copy()
    try:
        if boardPos == "up":
            cv.rectangle(moveAngleUsed, (0, 0), (moveWidth13, moveHeight), 0, -1)
            cv.rectangle(moveAngleUsed, (moveAngleUsed.shape[1], 0), (moveAngleUsed.shape[1] - moveWidth13, moveHeight), 0, -1)
            cv.rectangle(moveAngleUsed, (0, moveAngleUsed.shape[0] - moveHeight), (moveWidthMid, moveAngleUsed.shape[0]), 0, -1)
            cv.rectangle(moveAngleUsed, (moveAngleUsed.shape[1] - moveWidthMid, moveAngleUsed.shape[0] - moveHeight),
                         (moveAngleUsed.shape[1], moveAngleUsed.shape[0]), 0, -1)
        else:
            cv.rectangle(moveAngleUsed, (0, 0), (moveWidthMid, moveHeight), 0, -1)
            cv.rectangle(moveAngleUsed, (moveAngleUsed.shape[1], 0), (moveAngleUsed.shape[1] - moveWidthMid, moveHeight), 0, -1)
            cv.rectangle(moveAngleUsed, (0, moveAngleUsed.shape[0] - moveHeight), (moveWidth13, moveAngleUsed.shape[0]), 0, -1)
            cv.rectangle(moveAngleUsed, (moveAngleUsed.shape[1] - moveWidth13, moveAngleUsed.shape[0] - moveHeight),
                         (moveAngleUsed.shape[1], moveAngleUsed.shape[0]), 0, -1)

        image_show("MoveAngle", moveAngleUsed)

        cnts = cv.findContours(moveAngleUsed.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)
        cntsSorted = sorted(cnts, key=cv.contourArea, reverse=True)
        if len(cnts) == 0:
            res["result"] = "error"
            res["info"] = "{}框 找内板失败,没有找到任何的轮廓".format(boardPos)
            res["calcSize"] = (totalWidthMm, totalHeightMm)
            res["calcError"] = (round(totalWidthMm - widthMm, 2), round(totalHeightMm - heightMm, 2))
            return res
        cntFindAgain = False  # 是否要再找一遍轮廓
        _, (w, h), _ = cv.minAreaRect(cntsSorted[0])
        rectBox = cv.minAreaRect(cntsSorted[0])
        rectBoxPoints = np.int0(cv.boxPoints(rectBox))
        leftTop, rightTop, rightBottom, leftBottom = get_rect_points_clockwise(rectBoxPoints)
        useImage = boardColor.copy()
        cv.drawContours(useImage, [rectBoxPoints], -1, (0, 255, 0), 3)
        image_show("InnerBoardFinded", useImage)
        res["box"] = [leftTop, rightTop, rightBottom, leftBottom]
        widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
        heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
        res["calcSize"] = (widthFinded, heightFinded)
        res["calcError"] = (round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2))
        areaFinded = w * h
        if areaFinded < 0.7 * boardArea:
            res["result"] = "error"
            res["info"] = "{}框 找内板失败,找到的内板面积过小".format(boardPos)
            return res
        elif areaFinded > 1.3 * boardArea:
            res["result"] = "error"
            res["info"] = "{}框 找内板失败,找到的内板面积过大".format(boardPos)
            return res
        else:
            # 获取到物料边缘的距离,四个距离
            innerLine1 = [leftTop, rightTop]
            innerLine2 = [rightTop, rightBottom]
            innerLine3 = [rightBottom, leftBottom]
            innerLine4 = [leftBottom, leftTop]

            # 外层物料的四个顶点
            outterLine1 = [(0, 0), (totalWidthPix, 0)]
            outterLine2 = [(totalWidthPix, 0), (totalWidthPix, totalHeightPix)]
            outterLine3 = [(totalWidthPix, totalHeightPix), (0, totalHeightPix)]
            outterLine4 = [(0, totalHeightPix), (0, 0)]

            offsetTop = get_two_line_distance(innerLine1, outterLine1) / cp.mm2pix
            offsetRight = get_two_line_distance(innerLine2, outterLine2) / cp.mm2pix
            offsetBottom = get_two_line_distance(innerLine3, outterLine3) / cp.mm2pix
            offsetLeft = get_two_line_distance(innerLine4, outterLine4) / cp.mm2pix

            print("offsetMm: ({:.2f},{:.2f},{:.2f},{:.2f}), offsetPix: ({},{},{},{})".format(
                offsetTop, offsetRight, offsetBottom, offsetLeft, int(offsetTop * cp.mm2pix), int(offsetRight * cp.mm2pix),
                int(offsetBottom * cp.mm2pix), int(offsetLeft * cp.mm2pix)))
            if boardPos == "up":
                offsetTopLimit = 10
                offsetBottomLimit = upDownSlice / cp.mm2pix - 15
            else:
                offsetTopLimit = upDownSlice / cp.mm2pix - 15
                offsetBottomLimit = 10
            offsetLeftLimit = 10
            offsetRightLimit = 10

            findLineForMiddleFlag = False  # 中缝是否是通过找线来推测的
            # 推测第一边,如果找到的区域太靠近边缘,就重新找一次
            if offsetTop < offsetTopLimit and offsetBottom > offsetBottomLimit:
                findLineBoard = board.copy()[:int(board.shape[0] * 0.3), :]
                cv.destroyAllWindows()
                image_show("FindTopLineByLine", findLineBoard)
                scharrX = cv.Scharr(findLineBoard, cv.CV_64F, 1, 0)
                scharrY = cv.Scharr(findLineBoard, cv.CV_64F, 0, 1)
                scharrX = cv.convertScaleAbs(scharrX)
                scharrY = cv.convertScaleAbs(scharrY)
                scharrXY = cv.addWeighted(scharrX, 0.1, scharrY, 0.2, 0)
                findLineBoard = scharrXY.copy()
                image_show("ScharrXYFindTopLine", findLineBoard)
                lines = cv.HoughLinesP(findLineBoard, 1, np.pi / 180, 100, minLineLength, maxLineGap)
                boardShow = boardColor.copy()
                linesList = []
                colorIndex = 0
                for line in lines:
                    for x1, y1, x2, y2 in line:
                        lineLength = get_two_point_distance((x1, y1), (x2, y2))
                        if boardPos == "up":
                            yMin = 8 * cp.mm2pix
                            yMax = board.shape[0] - height - 10 * cp.mm2pix
                        else:
                            yMin = upDownSlice + 5 * cp.mm2pix
                            yMax = upDownSlice + 40 * cp.mm2pix
                        if abs(y2 - y1) < 10 * cp.mm2pix and abs(x2 - x1) > 5 * cp.mm2pix and yMin < y1 < yMax \
                                and yMin < y2 < yMax and lineLength > lineLengthMin:
                            linesList.append([x1, y1])
                            linesList.append([x2, y2])
                            cv.line(boardShow, (x1, y1), (x2, y2), colorList[colorIndex % 3], 3)
                            colorIndex += 1
                if len(linesList) >= 2:
                    image_show("TopLineFinded", boardShow)
                    cntFindAgain = True
                    if boardPos == "up" and not innerLine:
                        linesListFinal = sorted(linesList, key=lambda x: x[1])
                    else:
                        linesListFinal = sorted(linesList, key=lambda x: x[1], reverse=True)
                        findLineForMiddleFlag = True

                    targetLine = [linesListFinal[0], linesListFinal[1]]
                    y1 = targetLine[0][1]
                    y2 = targetLine[1][1]
                    # 按照最小的那个去截取
                    slicePos = int(min(y1, y2))
                    moveAngleUsed[:slicePos, :] = 0
                    image_show("moveAngleAfterSliceTop", moveAngleUsed)

            # 如果第一边是对的,推测第三边
            if offsetTop > offsetTopLimit and offsetBottom < offsetBottomLimit:
                yOffset = int(board.shape[0] * 0.5)
                findLineBoard = board.copy()[yOffset:, :]
                cv.destroyAllWindows()
                image_show("FindBottomLineByLine", findLineBoard)
                scharrX = cv.Scharr(findLineBoard, cv.CV_64F, 1, 0)
                scharrY = cv.Scharr(findLineBoard, cv.CV_64F, 0, 1)
                scharrX = cv.convertScaleAbs(scharrX)
                scharrY = cv.convertScaleAbs(scharrY)
                scharrXY = cv.addWeighted(scharrX, 0.1, scharrY, 0.2, 0)
                findLineBoard = scharrXY.copy()
                image_show("ScharrXYFindBottomLine", findLineBoard)
                lines = cv.HoughLinesP(findLineBoard, 1, np.pi / 180, 100, minLineLength, maxLineGap)
                boardShow = boardColor.copy()
                linesList = []
                colorIndex = 0
                for line in lines:
                    for x1, y1, x2, y2 in line:
                        y1 += yOffset
                        y2 += yOffset
                        lineLength = get_two_point_distance((x1, y1), (x2, y2))
                        if boardPos == "up":
                            yMin = boardShow.shape[0] - upDownSlice - 30 * cp.mm2pix
                            yMax = boardShow.shape[0] - upDownSlice + 5 * cp.mm2pix
                        else:
                            yMin = board.shape[0] - 100 * cp.mm2pix
                            yMax = board.shape[0] - 10 * cp.mm2pix

                        if abs(y2 - y1) < 10 * cp.mm2pix and abs(x2 - x1) > 5 * cp.mm2pix and yMin < y1 < yMax \
                                and yMin < y2 < yMax and lineLength > lineLengthMin:
                            linesList.append([x1, y1])
                            linesList.append([x2, y2])
                            cv.line(boardShow, (x1, y1), (x2, y2), colorList[colorIndex % 3], 3)
                            colorIndex += 1
                if len(linesList) >= 2:
                    image_show("BottomLineFinded", boardShow)
                    cntFindAgain = True
                    if boardPos == "up" or innerLine:
                        linesListFinal = sorted(linesList, key=lambda x: x[1])
                        if boardPos == "up":
                            findLineForMiddleFlag = True
                    else:
                        linesListFinal = sorted(linesList, key=lambda x: x[1], reverse=True)
                    targetLine = [linesListFinal[0], linesListFinal[1]]
                    y1 = targetLine[0][1]
                    y2 = targetLine[1][1]
                    slicePos = int(max(y1, y2))
                    moveAngleUsed[slicePos:, :] = 0
                    image_show("moveAngleAfterSliceBottom", moveAngleUsed)

            if widthFinded < widthMin or widthFinded > widthMax:  # 如果宽度识别的不对
                if (offsetRight > offsetRightLimit and offsetLeft < offsetLeftLimit) or innerLine:
                    # 推测左边的那条线
                    findLineBoard = board.copy()[:, :int(board.shape[1] * 0.2)]
                    cv.destroyAllWindows()
                    image_show("findLeftLineByLine", findLineBoard)
                    scharrX = cv.Scharr(findLineBoard, cv.CV_64F, 1, 0)
                    scharrY = cv.Scharr(findLineBoard, cv.CV_64F, 0, 1)
                    scharrX = cv.convertScaleAbs(scharrX)
                    scharrY = cv.convertScaleAbs(scharrY)
                    scharrXY = cv.addWeighted(scharrX, 0.2, scharrY, 0.1, 0)
                    findLineBoard = scharrXY.copy()
                    image_show("ScharrXYFindLeftLine", findLineBoard)
                    lines = cv.HoughLinesP(findLineBoard, 1, np.pi / 180, 100, minLineLength, maxLineGap)
                    boardShow = boardColor.copy()
                    linesList = []
                    colorIndex = 0
                    for line in lines:
                        for x1, y1, x2, y2 in line:
                            lineLength = get_two_point_distance((x1, y1), (x2, y2))
                            xMin = 10 * cp.mm2pix
                            xMax = boardShow.shape[1] * 0.3
                            if boardPos == "up":
                                yMin = 50 * cp.mm2pix
                                yMax = boardShow.shape[0] - upDownSlice - 30 * cp.mm2pix
                            else:
                                yMin = upDownSlice + 30 * cp.mm2pix
                                yMax = boardShow.shape[0] - 50 * cp.mm2pix
                            if abs(x2 - x1) < 5 * cp.mm2pix and abs(y2 - y1) > 10 * cp.mm2pix and xMin < x1 < xMax \
                                    and xMin < x2 < xMax and yMin < y1 < yMax and yMin < y2 < yMax and lineLength > lineLengthMin:
                                linesList.append([x1, y1])
                                linesList.append([x2, y2])
                                cv.line(boardShow, (x1, y1), (x2, y2), colorList[colorIndex % 3], 3)
                                colorIndex += 1

                    if len(linesList) >= 2:
                        image_show("LeftLineFinded", boardShow)
                        cntFindAgain = True
                        if innerLine:
                            linesListFinal = sorted(linesList, key=lambda x: x[0], reverse=True)
                        else:
                            linesListFinal = sorted(linesList, key=lambda x: x[0])

                        targetLine = [linesListFinal[0], linesListFinal[1]]
                        x1 = targetLine[0][0]
                        x2 = targetLine[1][0]
                        slicePos = int(min(x1, x2))
                        moveAngleUsed[:, :slicePos] = 0
                        image_show("moveAngleAfterSliceLeft", moveAngleUsed)

                if (offsetLeft > offsetLeftLimit and offsetRight < offsetRightLimit) or innerLine:
                    # 推测右边的那条线
                    xOffset = int(board.shape[1] * 0.75)
                    findLineBoard = board.copy()[:, xOffset:]
                    cv.destroyAllWindows()
                    image_show("findLeftLineByLine", findLineBoard)
                    scharrX = cv.Scharr(findLineBoard, cv.CV_64F, 1, 0)
                    scharrY = cv.Scharr(findLineBoard, cv.CV_64F, 0, 1)
                    scharrX = cv.convertScaleAbs(scharrX)
                    scharrY = cv.convertScaleAbs(scharrY)
                    scharrXY = cv.addWeighted(scharrX, 0.2, scharrY, 0.1, 0)
                    findLineBoard = scharrXY.copy()
                    image_show("ScharrXYFindRightLine", findLineBoard)
                    lines = cv.HoughLinesP(findLineBoard, 1, np.pi / 180, 100, minLineLength, maxLineGap)
                    boardShow = boardColor.copy()
                    linesList = []
                    colorIndex = 0
                    for line in lines:
                        for x1, y1, x2, y2 in line:
                            x1 += xOffset
                            x2 += xOffset
                            lineLength = get_two_point_distance((x1, y1), (x2, y2))
                            xMin = boardShow.shape[1] * 0.7
                            xMax = boardShow.shape[1] - 10 * cp.mm2pix
                            if boardPos == "up":
                                yMin = 50 * cp.mm2pix
                                yMax = boardShow.shape[0] - upDownSlice - 30 * cp.mm2pix
                            else:
                                yMin = upDownSlice + 30 * cp.mm2pix
                                yMax = boardShow.shape[0] - 50 * cp.mm2pix
                            if abs(x2 - x1) < 5 * cp.mm2pix and abs(y2 - y1) > 10 * cp.mm2pix and xMin < x1 < xMax and xMin < x2 < xMax \
                                    and lineLength > lineLengthMin and yMin < y1 < yMax and yMin < y2 < yMax:
                                linesList.append([x1, y1])
                                linesList.append([x2, y2])
                                cv.line(boardShow, (x1, y1), (x2, y2), colorList[colorIndex % 3], 3)
                                colorIndex += 1
                    if len(linesList) >= 2:
                        image_show("RightLineFinded", boardShow)
                        cntFindAgain = True
                        if innerLine:
                            linesListFinal = sorted(linesList, key=lambda x: x[0])
                        else:
                            linesListFinal = sorted(linesList, key=lambda x: x[0], reverse=True)

                        targetLine = [linesListFinal[0], linesListFinal[1]]
                        x1 = targetLine[0][0]
                        x2 = targetLine[1][0]
                        slicePos = int(max(x1, x2))
                        moveAngleUsed[:, slicePos:] = 0
                        image_show("moveAngleAfterSliceRight", moveAngleUsed)
            # 如果重新找线了,就再找一次轮廓
            if cntFindAgain:
                cnts = cv.findContours(moveAngleUsed.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
                cnts = imutils.grab_contours(cnts)
                cntsSorted = sorted(cnts, key=cv.contourArea, reverse=True)
                rectBox = cv.minAreaRect(cntsSorted[0])
                rectBoxPoints = np.int0(cv.boxPoints(rectBox))
                useImage = boardColor.copy()
                cv.drawContours(useImage, [rectBoxPoints], -1, (0, 255, 0), 3)
                image_show("InnerBoardFindedAfterFindLine", useImage)
                leftTop, rightTop, rightBottom, leftBottom = get_rect_points_clockwise(rectBoxPoints)
                res["box"] = leftTop, rightTop, rightBottom, leftBottom
                widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
                heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
                res["calcSize"] = widthFinded, heightFinded
                res["calcError"] = round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2)

            topLineAngle = get_angle_by_k(get_line_k_and_b(leftTop, rightTop)[0])
            if abs(topLineAngle) > 20:
                res["result"] = "error"
                res["info"] = "识别的内框的第一边的角度太大,角度为:{:.2f}".format(topLineAngle)
                res["calcSize"] = (widthFinded, heightFinded)
                res["calcError"] = (round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2))
                return res
            resByExtendFlag = False
            # 再计算一次是否有错误的信息
            innerLine1 = [leftTop, rightTop]
            # innerLine2 = [rightTop, rightBottom]
            innerLine3 = [rightBottom, leftBottom]
            # innerLine4 = [leftBottom, leftTop]
            offsetTop = get_two_line_distance(innerLine1, outterLine1) / cp.mm2pix
            # offsetRight = get_two_line_distance(innerLine2, outterLine2) / cp.mm2pix
            offsetBottom = get_two_line_distance(innerLine3, outterLine3) / cp.mm2pix
            # offsetLeft = get_two_line_distance(innerLine4, outterLine4) / cp.mm2pix

            if extendMiddle:
                if (boardPos == "up" and offsetTop > offsetTopLimit and (not heightMin < heightFinded < heightMax)) or \
                        (boardPos == "down" and offsetBottom > offsetBottomLimit and (not heightMin < heightFinded < heightMax)):
                    useImage = boardColor.copy()
                    newBox = get_new_box_by_edge_and_height([leftTop, rightTop, rightBottom, leftBottom], height, boardPos, useImage, upDownSlice)
                    if newBox is not None:
                        resByExtendFlag = True
                        res["box"] = newBox
                        leftTop, rightTop, rightBottom, leftBottom = newBox
                        widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
                        heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
                        res["calcSize"] = (widthFinded, heightFinded)
                        res["calcError"] = round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2)
                        res["info"] = "识别成功,通过第一边推测中缝." if boardPos == "up" else "识别成功,通过第三边推测中缝."
                        useImage = boardColor.copy()
                        cv.drawContours(useImage, [np.array(newBox)], -1, (0, 255, 0), 3)
                        image_show("InnerBoardFindedByExtendForMiddle", useImage)

            # 通过中缝推测另外一边,如果中缝不是推测的
            if (heightFinded < heightMin or heightFinded > heightMax) and widthMin < widthFinded < widthMax and not findLineForMiddleFlag:
                middlineY = get_two_points_middle(leftTop, rightTop)[1] if boardPos == "down" else get_two_points_middle(leftBottom, rightBottom)[1]
                totalBoardMiddle = upDownSlice if boardPos == "down" else board.shape[0] - upDownSlice

                if ((totalBoardMiddle - middlineY) > 5 * cp.mm2pix and boardPos == "up") or \
                        ((totalBoardMiddle - middlineY) < -15 * cp.mm2pix and boardPos == "down"):
                    middleIsOk = True
                else:
                    middleIsOk = False

                if middleIsOk:
                    newBox = get_new_box_by_middle_and_height([leftTop, rightTop, rightBottom, leftBottom], height, boardPos, boardColor)
                    if newBox is not None:
                        res["box"] = newBox
                        resByExtendFlag = True
                        leftTop, rightTop, rightBottom, leftBottom = newBox
                        widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
                        heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
                        res["calcSize"] = (widthFinded, heightFinded)
                        res["calcError"] = (round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2))
                        res["info"] = "识别成功,通过中缝推测第一边" if boardPos == "up" else "识别成功,通过中缝推测第三边"
            if isFirstCheck:
                if widthFinded < widthMin or heightFinded < heightMin:
                    res["result"] = "small"
                    res["info"] = "{} 框,识别尺寸过小,识别尺寸: {}".format(boardPos, res["calcSize"])
                    return res
                if widthFinded > widthMax or heightFinded > heightMax:
                    res["result"] = "big"
                    res["info"] = "{} 框,识别尺寸过大,识别尺寸: {}".format(boardPos, res["calcSize"])
                    return res
            else:
                if widthFinded < widthMin or widthFinded > widthMax:
                    otherLineIsOk, newBox = check_other_line_is_ok(board, res["box"], offset, "24", width, boardPos)
                    if otherLineIsOk:
                        res["box"] = newBox
                        resByExtendFlag = True
                        leftTop, rightTop, rightBottom, leftBottom = get_rect_points_clockwise(newBox)
                        widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
                        heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
                        res["calcSize"] = widthFinded, heightFinded
                        res["calcError"] = round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2)
                        res["info"] = "识别成功,2,4边通过一边推测另外一边"
                        useImage = boardColor.copy()
                        cv.drawContours(useImage, [np.array(newBox)], -1, colorGreen, 3)
                        image_show("InnerBoardFindedByCalc24", useImage)
                    else:
                        if widthFinded < widthMin:
                            res["result"] = "small"
                            res["info"] = "宽度识别过小,识别尺寸:{},识别误差:{}".format(res["calcSize"], res["calcError"])
                            return res
                        if widthFinded > widthMax:
                            res["result"] = "big"
                            res["info"] = "宽度识别过大,识别尺寸:{},识别误差:{}".format(res["calcSize"], res["calcError"])
                            return res

                if heightFinded < heightMin or heightFinded > heightMax:
                    otherLineIsOk, newBox = check_other_line_is_ok(board, res["box"], offset, "13", height, boardPos)
                    if otherLineIsOk:
                        res["box"] = newBox
                        resByExtendFlag = True
                        leftTop, rightTop, rightBottom, leftBottom = get_rect_points_clockwise(newBox)
                        widthFinded = round(get_two_point_distance(leftTop, rightTop) / cp.mm2pix, 2)
                        heightFinded = round(get_two_point_distance(leftTop, leftBottom) / cp.mm2pix, 2)
                        res["calcSize"] = widthFinded, heightFinded
                        res["calcError"] = round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2)
                        res["info"] = "识别成功,1,3边通过一边推测另外一边"
                        useImage = boardColor.copy()
                        cv.drawContours(useImage, [np.array(newBox)], -1, colorGreen, 3)
                        image_show("InnerBoardFindedByCalc13", useImage)
                    else:
                        if heightFinded < heightMin:
                            res["result"] = "small"
                            res["info"] = "高度识别过小,识别尺寸:{},识别误差:{}".format(res["calcSize"], res["calcError"])
                            return res
                        if heightFinded > heightMax:
                            res["result"] = "big"
                            res["info"] = "高度识别过大,识别尺寸:{},识别误差:{}".format(res["calcSize"], res["calcError"])
                            return res

            # 再次计算一下有没有错误的边信息,主要是不是离物料边缘太近.
            innerLine1 = [leftTop, rightTop]
            innerLine2 = [rightTop, rightBottom]
            innerLine3 = [rightBottom, leftBottom]
            innerLine4 = [leftBottom, leftTop]
            offsetTop = get_two_line_distance(innerLine1, outterLine1) / cp.mm2pix
            offsetRight = get_two_line_distance(innerLine2, outterLine2) / cp.mm2pix
            offsetBottom = get_two_line_distance(innerLine3, outterLine3) / cp.mm2pix
            offsetLeft = get_two_line_distance(innerLine4, outterLine4) / cp.mm2pix
            if min(offsetTop, offsetRight, offsetBottom, offsetLeft) < 6:
                res["info"] = "识别的内框太靠近物料边缘: ({:.2f},{:.2f},{:.2f},{:.2f})".format(offsetTop, offsetRight, offsetBottom, offsetLeft)
                res["calcSize"] = widthFinded, heightFinded
                res["calcError"] = round(widthFinded - widthMm, 2), round(heightFinded - heightMm, 2)
                return res
            boxFinded = res["box"]
            if boardPos == "down":
                downBoxPoints = [(p[0], p[1] + heightHalf - upDownSlice) for p in boxFinded]
                # 检测是否叠板
                isOverlap = check_two_box_is_overlap(upBox, downBoxPoints)
                if isOverlap:
                    totalBoardColor = cv.cvtColor(totalBoard, cv.COLOR_GRAY2BGR)
                    cv.drawContours(totalBoardColor, [np.array(upBox), np.array(downBoxPoints)], -1, colorGreen, 3)
                    image_show("BoardOverLap", totalBoardColor)
                    res["result"] = "error"
                    res["info"] = "上下框出现叠板,识别失败~"
                    return res

            if resByExtendFlag:
                res["result"] = "okByExtend"
            else:
                res["result"] = "ok"
                res["info"] = "识别成功!"
            return res
    except Exception as e:
        errorInfo = "in check_inner_board_2p(),error: {}".format(str(e))
        print(errorInfo)
        res["result"] = "error"
        res["info"] = errorInfo
        res["calcSize"] = (totalWidthMm, totalHeightMm)
        res["calcError"] = (round(totalWidthMm - width / cp.mm2pix, 2), round(totalHeightMm - height / cp.mm2pix, 2))
        return res


def get_inner_board_info_2p(board, jointLine1, jointLine2, width, height, calcThresBig, calcThresSmall, boardPos,
                            isFirstCheck=False, upBox=None, heightHalf=None, offset=None, isSizeCheck=False, totalBoard=None):
    """
    获取内板信息,双拼板获取内板信息
    :param board: 内板原图
    :param jointLine1: 拼接处填充方式1,在使用梯度的时候填充, 填充的mask中间是一条黑线.
    :param jointLine2: 拼接处填充方式2,在使用正常算法的时候使用, 填充的mask,中间是一条白线
    :param width: 内板的宽
    :param height: 内板的高
    :param calcThresBig: 尺寸偏大阈值
    :param calcThresSmall: 尺寸偏小阈值
    :param boardPos: 板的位置信息
    :param isFirstCheck: 是否是首板
    :param upBox: 上框的位置信息,在找下框的时候才会用到
    :param heightHalf: 物料高度的一半
    :param offset: 首板记录的识别的边到物料边缘的距离
    :param isSizeCheck: 是否是尺寸确认的时候调用
    :return:
    """
    boardColor = cv.cvtColor(board.copy(), cv.COLOR_GRAY2BGR)
    sizeOkByExtendRes = []
    sizeDifRes = []
    sizeOkRes = []
    calcArgs = calcArgsNormal
    print("in get_inner_board_info_2p() isFirstCheck = {}".format(isFirstCheck))

    for tryTimes in range(tryBeginIndex, len(calcArgs.keys()) + 1):
        cv.destroyAllWindows()
        gaussianR, squareR, dilateKernel, dilateTimes, erodeTimes, thresOffsetList, scharrRate = calcArgs.get(str(tryTimes))
        print("第{}次计算,计算参数:(高斯半径:{},方差核:{},膨胀腐蚀核:{},膨胀腐蚀次数:{},腐蚀膨胀次数:{},阈值offset:{},scharr比例:{})".format(
            tryTimes, gaussianR, squareR, dilateKernel, dilateTimes, erodeTimes, thresOffsetList, scharrRate))

        if len(gaussianR) == 1:
            if gaussianR[0] == 0:
                blurred = board.copy()
            else:
                blurred = cv.GaussianBlur(board, (0, 0), gaussianR[0])
        else:
            d, colorSigma = gaussianR
            spaceSigma = int(d / 2)
            blurred = cv.bilateralFilter(board, d, colorSigma, spaceSigma)

        if scharrRate == 0:
            scharrXY = blurred.copy()
        else:
            scharrX = cv.Scharr(blurred, cv.CV_64F, 1, 0)
            scharrY = cv.Scharr(blurred, cv.CV_64F, 0, 1)
            scharrX = cv.convertScaleAbs(scharrX)
            scharrY = cv.convertScaleAbs(scharrY)
            scharrXY = cv.addWeighted(scharrX, scharrRate, scharrY, scharrRate, 0)
            scharrXY = cv.convertScaleAbs(scharrXY)
            scharrXY = cv.bitwise_and(scharrXY, jointLine1)
        image_show("ScharrXY", scharrXY)
        img32 = np.float32(scharrXY)
        square1 = cv.blur(np.multiply(img32, img32), (squareR, squareR))
        square2 = np.multiply(cv.blur(img32, (squareR, squareR)), cv.blur(img32, (squareR, squareR)))
        squareDif32 = np.subtract(square1, square2)
        squareDif = squareDif32.copy()
        np.clip(squareDif32, 0, 255, out=squareDif)
        squareDif = squareDif.astype("uint8")
        image_show("SquareDif", squareDif)

        # 进行膨胀腐蚀,分割图像
        contourImg = squareDif.copy()
        kernelUsed = cv.getStructuringElement(cv.MORPH_RECT, (dilateKernel, dilateKernel))
        contourImg = cv.dilate(contourImg, kernelUsed, iterations=dilateTimes)
        contourImg = cv.erode(contourImg, kernelUsed, iterations=dilateTimes)
        image_show("squareDifDilateErore", contourImg)

        squareDifErode = contourImg.copy()
        for index, thresOffset in enumerate(thresOffsetList):
            cv.destroyAllWindows()
            image_show("squareDifDilateErode", squareDifErode)
            # 根据阈值进行分割
            centerX, centerY = int(squareDifErode.shape[1] / 2), int(squareDifErode.shape[0] / 2)
            yChoosePos = int(0.25 * squareDifErode.shape[0])
            xChoosePos = int(0.25 * squareDifErode.shape[1])
            thresUsed = squareDifErode[centerY - yChoosePos:centerY + yChoosePos, centerX - xChoosePos:centerX + xChoosePos]
            chooseRoiThres = int(np.mean(thresUsed))
            thresUsedReal = chooseRoiThres + thresOffset
            print("第 {} 个阈值,使用的实际阈值:{},参考的中心区域亮度值:{},thresOffset:{}".format(index + 1, thresUsedReal, chooseRoiThres, thresOffset))
            _, contourImg = cv.threshold(squareDifErode, thresUsedReal, 255, cv.THRESH_BINARY)

            # 如果是另外一种情况没有使用梯度的时候,拼接处的另外一种处理方式
            if scharrRate == 0:
                contourImg = cv.subtract(contourImg, jointLine2)

            # 4. 进行泛洪填充,要考虑一种情况是,填充选择的点刚好不是黑点,是个白点的情况.要重新再选一次
            mask = np.zeros((contourImg.shape[0] + 2, contourImg.shape[1] + 2), dtype=np.uint8)
            if contourImg[contourImg.shape[0] // 2, contourImg.shape[1] // 2] > 150:
                cv.floodFill(contourImg, mask, (contourImg.shape[1] // 3, contourImg.shape[0] // 3), 150)
            else:
                cv.floodFill(contourImg, mask, (contourImg.shape[1] // 2, contourImg.shape[0] // 2), 150)

            floodFill = np.zeros(contourImg.shape, dtype=np.uint8)
            floodFill[contourImg == 150] = 250
            image_show("FloodFill", floodFill)

            if len(gaussianR) == 1 and gaussianR[0] >= 10:
                innerLine = True  # 是否按照从内往外找
            else:
                innerLine = False

            if tryTimes == 5:
                extendMiddle = True
            else:
                extendMiddle = False

            # 进行腐蚀膨胀,去除掉边界的噪点
            floodFill = cv.erode(floodFill, kernelUsed, iterations=erodeTimes)
            floodFill = cv.dilate(floodFill, kernelUsed, iterations=erodeTimes)
            image_show("FloodFillErodeDilate", floodFill)
            res = check_inner_board_2p(floodFill, width, height, calcThresBig, calcThresSmall, boardColor,
                                       boardPos, upBox, heightHalf, innerLine, extendMiddle, isFirstCheck, offset, totalBoard)
            print("计算结果:{},{},识别尺寸:{},{},误差:{}".format(res["result"], res["info"], res["calcSize"],
                                                       (int(res["calcSize"][0] * cp.mm2pix), int(res["calcSize"][1] * cp.mm2pix)), res["calcError"]))
            if res["result"] == "ok":
                sizeOkRes.append(res)
                calcSize = res["calcSize"]
                calcError = res["calcError"]
                if get_sum_abs(calcError) < 7 and not isFirstCheck:  # 如果不是做首片,并且误差之后小于7就直接返回
                    print("返回的ok结果是:算子编号和亮度阈值:({},{}),尺寸:{},{},误差:{}".format(tryTimes, thresOffset, calcSize,
                                                                             (int(calcSize[0] * cp.mm2pix), int(calcSize[1] * cp.mm2pix)), calcError))
                    return "ok", res["info"], res["box"]
                continue
            elif res["result"] == "okByExtend":
                if isFirstCheck:
                    sizeOkRes.append(res)
                else:
                    sizeOkByExtendRes.append(res)
                continue
            elif res["result"] != "error":
                sizeDifRes.append(res)
                if res["result"] == "big" and not innerLine and not extendMiddle:
                    break
                if res["result"] == "small":
                    continue
                continue
    else:
        # 最外成循环都结束之后.
        if isFirstCheck and isSizeCheck:
            sizeList = []
            boxList = []
            if len(sizeOkRes) >= 1:
                resOkSorted = sorted(sizeOkRes, key=lambda x: get_sum_abs(x["calcError"]))
                for res in resOkSorted:
                    sizeList.append(res["calcSize"])
                    boxList.append(res["box"])
                return "ok", sizeList, boxList

            if len(sizeOkByExtendRes) >= 1:
                resOkSorted = sorted(sizeOkByExtendRes, key=lambda x: get_sum_abs(x["calcError"]))
                for res in resOkSorted:
                    sizeList.append(res["calcSize"])
                    boxList.append(res["box"])
                return "ok", sizeList, boxList

            if len(sizeDifRes) >= 1:
                resSizeDifList = sorted(sizeDifRes, key=lambda x: get_sum_abs(x["calcError"]))
                for res in resSizeDifList:
                    sizeList.append(res["calcSize"])
                    boxList.append(res["box"])
                return "sizeDif", sizeList, boxList

            else:
                return "error", "内板寻找失败", None
        else:
            if len(sizeOkRes) >= 1:
                resOkSorted = sorted(sizeOkRes, key=lambda x: get_sum_abs(x["calcError"]))
                res = resOkSorted[0]
                print("返回的ok结果是:尺寸:{},{},误差:{}".format(
                    res["calcSize"], (int(res["calcSize"][0] * cp.mm2pix), int(res["calcSize"][1] * cp.mm2pix)), res["calcError"]))
                return "ok", res["info"], res["box"]

            if len(sizeOkByExtendRes) >= 1:
                resOkSorted = sorted(sizeOkByExtendRes, key=lambda x: get_sum_abs(x["calcError"]))
                res = resOkSorted[0]
                print("返回的ok结果是:尺寸:{},{},误差:{}".format(
                    res["calcSize"], (int(res["calcSize"][0] * cp.mm2pix), int(res["calcSize"][1] * cp.mm2pix)), res["calcError"]))
                return "ok", res["info"], res["box"]

            if len(sizeDifRes) >= 1:
                resDifSorted = sorted(sizeDifRes, key=lambda x: get_sum_abs(x["calcError"]))
                res = resDifSorted[0]
                return "sizeDif", res["info"], res["box"]
            else:
                return "error", "找内板失败", None


def get_size_check_result_2p(image, width, height, calcThresBig, totalBoardBox, totalBoard):
    """
    两拼板获取尺寸确认的结果
    :param image: 原图
    :param width: 内板的宽
    :param height: 内板的高
    :param calcThresBig: 偏大阈值
    :param totalBoardBox: 物料区域的位置信息 (centerX,centerY),(w,h), angle
    :param totalBoard: 整个物料区域的图
    :return:
    """
    print("in get_size_check_result_2p()")
    if image is None:
        return "error", None, None, None
    jointLineMask1 = np.ones(image.shape, dtype=np.uint8) * 255
    jointLineMask1[:, cp.middleJointPos - jointLineExtend:cp.middleJointPos + jointLineExtend] = 0
    jointLineMaskNoAngle1, _ = get_board_without_angle(jointLineMask1, totalBoardBox)

    jointLineMask2 = np.zeros(image.shape, dtype=np.uint8)
    jointLineMask2[:, cp.middleJointPos - jointLineExtend:cp.middleJointPos + jointLineExtend] = 255
    jointLineMaskNoAngle2, _ = get_board_without_angle(jointLineMask2, totalBoardBox)
    cv.destroyAllWindows()
    image_show("TotalBoard", totalBoard)

    w, h = totalBoardBox[1]
    heightHalf = int(h / 2)
    upBoard = totalBoard.copy()[:int(heightHalf + upDownSlice), :]
    upJointLine1 = jointLineMaskNoAngle1.copy()[:int(heightHalf + upDownSlice), :]
    upJointLine2 = jointLineMaskNoAngle2.copy()[:int(heightHalf + upDownSlice), :]
    upBoardColor = cv.cvtColor(upBoard, cv.COLOR_GRAY2BGR)

    upRes, upSizes, upBoxes = get_inner_board_info_2p(upBoard, upJointLine1, upJointLine2, width, height, calcThresBig, calcThresBig, "up",
                                                      isFirstCheck=True, upBox=None, heightHalf=heightHalf, offset=None, isSizeCheck=True,
                                                      totalBoard=totalBoard)
    upBoardResList = []
    upSizeResList = []
    if upRes != "error":
        for index, upBox in enumerate(upBoxes):
            if upBox is not None:
                upBoardRes = upBoardColor.copy()
                cv.drawContours(upBoardRes, [np.array(upBox)], -1, colorGreen, 3)
                centerX, centerY = upBoard.shape[1] // 2, upBoard.shape[0] // 2
                cv.putText(upBoardRes, "{}".format(index + 1), (centerX - 8, centerY), cv.FONT_HERSHEY_COMPLEX, 10, colorBlue, 5)
                image_show("upBoardRes", upBoardRes)
                upBoardResList.append(upBoardRes)
                upSizeResList.append(upSizes[index])
        return "ok", upSizeResList, upBoardResList, upBoardColor
    else:
        return "error", "内板识别出错", None, upBoardColor


def get_boxes_2pin(image, width, height, calcThresBig, calcThresSmall, totalBoardBox, totalBoard, upLineOffset, downLineOffset, isFirstBoard):
    """
    两拼板,获取内板的信息.
    :param image:
    :param width:
    :param height:
    :param calcThresBig:
    :param calcThresSmall:
    :param totalBoardBox:
    :param totalBoard:
    :param upLineOffset:
    :param downLineOffset:
    :param isFirstBoard:
    :return:
    """
    print("in get_boxes_2pin(),isFirstBoard: {}".format(isFirstBoard))
    if image is None:
        return "error", None, None, None

    jointLineMask1 = np.ones(image.shape, dtype=np.uint8) * 255
    jointLineMask1[:, cp.middleJointPos - jointLineExtend:cp.middleJointPos + jointLineExtend] = 0
    jointLineMaskNoAngle1, _ = get_board_without_angle(jointLineMask1, totalBoardBox)
    jointLineMask2 = np.zeros(image.shape, dtype=np.uint8)
    jointLineMask2[:, cp.middleJointPos - jointLineExtend:cp.middleJointPos + jointLineExtend] = 255
    jointLineMaskNoAngle2, _ = get_board_without_angle(jointLineMask2, totalBoardBox)
    cv.destroyAllWindows()
    image_show("TotalBoard", totalBoard)

    w, h = totalBoardBox[1]
    heightHalf = int(h / 2)
    upBoard = totalBoard.copy()[:int(heightHalf + upDownSlice), :]
    upJointLine1 = jointLineMaskNoAngle1.copy()[:int(heightHalf + upDownSlice), :]
    upJointLine2 = jointLineMaskNoAngle2.copy()[:int(heightHalf + upDownSlice), :]
    downBoard = totalBoard.copy()[int(heightHalf - upDownSlice):, :]
    downJointLine1 = jointLineMaskNoAngle1.copy()[int(heightHalf - upDownSlice):, :]
    downJointLine2 = jointLineMaskNoAngle2.copy()[int(heightHalf - upDownSlice):, :]

    # 如果是首片,返回值是一个列表.
    upRes, upInfo, upBox = get_inner_board_info_2p(upBoard, upJointLine1, upJointLine2, width, height, calcThresBig,
                                                   calcThresSmall, "up", isFirstCheck=isFirstBoard, offset=upLineOffset, isSizeCheck=False,
                                                   totalBoard=totalBoard)
    if upRes != "ok":
        return False, upInfo, upBox, None

    downRes, downInfo, downBox = get_inner_board_info_2p(downBoard, downJointLine1, downJointLine2, width, height, calcThresBig, calcThresSmall,
                                                         "down", isFirstCheck=isFirstBoard, upBox=upBox, heightHalf=heightHalf, offset=downLineOffset,
                                                         isSizeCheck=False, totalBoard=totalBoard)
    if downRes != "ok":
        return False, downInfo, upBox, downBox
    downBoxPoints = [(p[0], p[1] + heightHalf - upDownSlice) for p in downBox]
    totalBoardColor = cv.cvtColor(totalBoard, cv.COLOR_GRAY2BGR)
    cv.drawContours(totalBoardColor, [np.array(upBox), np.array(downBoxPoints)], -1, colorGreen, 3)
    image_show("TwoBoxes", totalBoardColor)
    downBox = downBoxPoints
    return True, "识别成功", upBox, downBox


def get_lines_with_boxes_2p(image, totalBoard, totalBoardBox, totalBoardThres, upBox, downBox, transMtx, topRemain, leftRemain,
                            bottomRemain, rightRemain, totalBoardOffset):
    """
    根据两个内框的信息,以及标定矩阵,或者切线信息.
    :param image:
    :param totalBoard:
    :param totalBoardBox:
    :param totalBoardThres:
    :param upBox:
    :param downBox:
    :param transMtx:
    :param topRemain:
    :param leftRemain:
    :param bottomRemain:
    :param rightRemain:
    :param totalBoardOffset:
    :return:
    """
    if len(image.shape) == 3:
        image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    imageColor = cv.cvtColor(image, cv.COLOR_GRAY2BGR)
    (centerX, centerY), (w, h), totalBoardAngle = totalBoardBox
    upLeftTop, upRightTop, upRightBottom, upLeftBottom = upBox
    downLeftTop, downRightTop, downRightBottom, downLeftBottom = downBox

    # 获取垂直方向的拟合直线
    leftCutLineK = get_linear_fit_k_vertical(np.array([upLeftTop, upLeftBottom, downLeftTop, downLeftBottom]))
    # 直接分别求四个点的直线的b参数,找出最值,目标就是选一条线,使得四个点都在这条线的右侧
    if leftCutLineK is None:
        # 如果是垂直的线,就按照x轴坐标的最小值来确定
        leftCutLineB = min(upLeftTop[0], upLeftBottom[0], downLeftTop[0], downLeftBottom[0]) - leftRemain
    else:
        upLeftTopB = upLeftTop[1] - (upLeftTop[0] - leftRemain) * leftCutLineK
        upLeftBottomB = upLeftBottom[1] - (upLeftBottom[0] - leftRemain) * leftCutLineK
        downLeftTopB = downLeftTop[1] - (downLeftTop[0] - leftRemain) * leftCutLineK
        downLeftBottomB = downLeftBottom[1] - (downLeftBottom[0] - leftRemain) * leftCutLineK

        if leftCutLineK > 0:
            # 当k大于0的时候,b越大,越靠左.
            leftCutLineB = max(upLeftTopB, upLeftBottomB, downLeftTopB, downLeftBottomB)
        else:
            leftCutLineB = min(upLeftTopB, upLeftBottomB, downLeftTopB, downLeftBottomB)

    rightCutLineK = get_linear_fit_k_vertical(np.array([upRightBottom, upRightTop, downRightTop, downRightBottom]))
    # 直接分别求过四个点的直线的b参数，找出最值
    if rightCutLineK is None:
        rightCutLineB = max(upRightTop[0], upRightBottom[0], downRightTop[0], downRightBottom[0]) + rightRemain
    else:
        upRightTopB = upRightTop[1] - (upRightTop[0] + rightRemain) * rightCutLineK
        upRightBottomB = upRightBottom[1] - (upRightBottom[0] + rightRemain) * rightCutLineK
        downRightTopB = downRightTop[1] - (downRightTop[0] + rightRemain) * rightCutLineK
        downRightBottomB = downRightBottom[1] - (downRightBottom[0] + rightRemain) * rightCutLineK

        if rightCutLineK > 0:  # 当k大于0时，b越大，越靠左
            rightCutLineB = min(upRightTopB, upRightBottomB, downRightTopB, downRightBottomB)
        else:  # 当k小于0时，b越小，越靠左
            rightCutLineB = max(upRightTopB, upRightBottomB, downRightTopB, downRightBottomB)

    topCutLineK = get_line_k_and_b(upLeftTop, upRightTop)[0]
    if topCutLineK is None:
        cv.destroyAllWindows()
        return False, None, None, None, None, None
    else:
        topCutLineB = (upLeftTop[1] - topRemain) - topCutLineK * upLeftTop[0]

    bottomCutLineK = get_line_k_and_b(downLeftBottom, downRightBottom)[0]
    if bottomCutLineK is None:
        cv.destroyAllWindows()
        return False, None, None, None, None, None
    else:
        bottomCutLineB = (downLeftBottom[1] + bottomRemain) - bottomCutLineK * downLeftBottom[0]

    # 物料区域的四个顶点
    boardLeftTop = [0, 0]
    boardRightTop = [w, 0]
    boardRightBottom = [w, h]
    boardLeftBottom = [0, h]

    # 这个地方根据情况要不要加.就是计算切线是否在物料区域边缘之外,如果切线超出了物料区域范围,就加上这个,如果没有,就不加
    # 去除掉自动不切的逻辑
    leftTopY = upLeftTop[1] - topRemain
    rightTopY = upRightTop[1] - topRemain
    if leftTopY < 0 or rightTopY < 0:
        topRemain = 0
    leftBottomY = downLeftBottom[1] + bottomRemain
    rightBottomY = downRightBottom[1] + bottomRemain
    if leftBottomY > totalBoard.shape[0] or rightBottomY > totalBoard.shape[0]:
        bottomRemain = 0

    findEdgeExtend = int(7 * cp.mm2pix)  # 找边缘的时候延长10个mm
    totalBoardExtendForFindEdge, _ = get_board_without_angle(image, totalBoardBox, findEdgeExtend)
    totalBoardThresForFindEdge, _ = get_board_without_angle(totalBoardThres, totalBoardBox, findEdgeExtend)
    if topRemain == 0:
        topLineK, topLineB = find_first_edge_line(totalBoardExtendForFindEdge, totalBoardThresForFindEdge, findEdgeExtend)
        if topLineK is not None:
            topCutLineK, topCutLineB = topLineK, topLineB
        else:
            topCutLineK, topCutLineB = get_line_k_and_b(boardLeftTop, boardRightTop)

    if bottomRemain == 0:
        bottomLineK, bottomLineB = find_third_edge_line(totalBoardExtendForFindEdge, totalBoardThresForFindEdge, findEdgeExtend)
        if bottomLineK is not None:
            bottomCutLineK, bottomCutLineB = bottomLineK, bottomLineB
        else:
            bottomCutLineK, bottomCutLineB = get_line_k_and_b(boardLeftBottom, boardRightBottom)

    if leftRemain == 0:
        leftCutLineK, leftCutLineB = get_line_k_and_b(boardLeftBottom, boardLeftTop)

    if rightRemain == 0:
        rightCutLineK, rightCutLineB = get_line_k_and_b(boardRightTop, boardRightBottom)

    # 求所有的交点
    leftTopCross = get_two_lines_intersection(topCutLineK, topCutLineB, leftCutLineK, leftCutLineB)
    rightTopCross = get_two_lines_intersection(topCutLineK, topCutLineB, rightCutLineK, rightCutLineB)
    leftBottomCross = get_two_lines_intersection(bottomCutLineK, bottomCutLineB, leftCutLineK, leftCutLineB)
    rightBottomCross = get_two_lines_intersection(bottomCutLineK, bottomCutLineB, rightCutLineK, rightCutLineB)
    if leftTopCross[0] is None or rightTopCross[0] is None or leftBottomCross[0] is None or rightBottomCross[0] is None:
        return False, None, None, None, None, None

    extend13 = int(18 * cp.mm2pix)  # 1.3刀的延长线
    extend24 = int(23 * cp.mm2pix)  # 2.4刀的延长线

    topCutLeftPoint = [-extend13, topCutLineK * (-extend13) + topCutLineB]
    topCutRightPoint = [extend13 + w, topCutLineK * (extend13 + w) + topCutLineB]
    bottomCutLeftPoint = [-extend13, bottomCutLineK * (-extend13) + bottomCutLineB]
    bottomCutRightPoint = [w + extend13, bottomCutLineK * (w + extend13) + bottomCutLineB]

    if leftCutLineK is None:
        leftCutLineTop = [leftCutLineB, leftTopCross[1] - extend24]
        leftCutLineBottom = [leftCutLineB, leftBottomCross[1] + extend24]
    elif leftCutLineK != 0:
        leftCutLineTop = [(leftTopCross[1] - extend24 - leftCutLineB) / leftCutLineK, leftTopCross[1] - extend24]
        leftCutLineBottom = [(leftBottomCross[1] + extend24 - leftCutLineB) / leftCutLineK, leftBottomCross[1] + extend24]
    else:
        cv.destroyAllWindows()
        return False, None, None, None, None, None

    if rightCutLineK is None:
        rightCutLineTop = [rightCutLineB, rightTopCross[1] - extend24]
        rightCutLineBottom = [rightCutLineB, rightBottomCross[1] + extend24]
    elif rightCutLineK != 0:
        rightCutLineTop = [(rightTopCross[1] - extend24 - rightCutLineB) / rightCutLineK, rightTopCross[1] - extend24]
        rightCutLineBottom = [(rightBottomCross[1] + extend24 - rightCutLineB) / rightCutLineK, rightBottomCross[1] + extend24]
    else:
        cv.destroyAllWindows()
        return False, None, None, None, None, None

    # 求中线,求角平分线
    middleCutLineK, middleCutLineB = get_middle_cut_line(upLeftBottom, upRightBottom, downLeftTop, downRightTop)
    leftMiddleCross = get_two_lines_intersection(middleCutLineK, middleCutLineB, leftCutLineK, leftCutLineB)
    rightMiddleCross = get_two_lines_intersection(middleCutLineK, middleCutLineB, rightCutLineK, rightCutLineB)
    middleCutLineLeft = [leftMiddleCross[0] - 10, middleCutLineK * (leftMiddleCross[0] - 10) + middleCutLineB]
    middleCutLineRight = [rightMiddleCross[0] + 10, middleCutLineK * (rightMiddleCross[0] + 10) + middleCutLineB]

    # 将所有的点转换到大图上去,注意大图边小图是先旋转然后截图,所以定位到大图上去,也是先补偿x和y的坐标,然后再旋转
    rotatedCenter = (centerX, centerY)
    M = cv.getRotationMatrix2D(rotatedCenter, -totalBoardAngle, 1)
    centerOffset = totalBoardOffset
    boardLeftTopBig = np.dot(M, [boardLeftTop[0] + centerOffset[0], boardLeftTop[1] + centerOffset[1], 1])
    boardRightTopBig = np.dot(M, [boardRightTop[0] + centerOffset[0], boardRightTop[1] + centerOffset[1], 1])
    boardRightBottomBig = np.dot(M, [boardRightBottom[0] + centerOffset[0], boardRightBottom[1] + centerOffset[1], 1])
    boardLeftBottomBig = np.dot(M, [boardLeftBottom[0] + centerOffset[0], boardLeftBottom[1] + centerOffset[1], 1])

    topCutLeftPointBig = np.dot(M, [topCutLeftPoint[0] + centerOffset[0], topCutLeftPoint[1] + centerOffset[1], 1])
    topCutRightPointBig = np.dot(M, [topCutRightPoint[0] + centerOffset[0], topCutRightPoint[1] + centerOffset[1], 1])

    bottomCutRightPointBig = np.dot(M, [bottomCutRightPoint[0] + centerOffset[0], bottomCutRightPoint[1] + centerOffset[1], 1])

    bottomCutLeftPointBig = np.dot(M, [bottomCutLeftPoint[0] + centerOffset[0], bottomCutLeftPoint[1] + centerOffset[1], 1])

    leftCutLineBottomBig = np.dot(M, [leftCutLineBottom[0] + centerOffset[0], leftCutLineBottom[1] + centerOffset[1], 1])

    leftCutLineTopBig = np.dot(M, [leftCutLineTop[0] + centerOffset[0], leftCutLineTop[1] + centerOffset[1], 1])
    rightCutLineTopBig = np.dot(M, [rightCutLineTop[0] + centerOffset[0], rightCutLineTop[1] + centerOffset[1], 1])
    rightCutLineBottomBig = np.dot(M, [rightCutLineBottom[0] + centerOffset[0], rightCutLineBottom[1] + centerOffset[1], 1])
    middleCutLineLeftBig = np.dot(M, [middleCutLineLeft[0] + centerOffset[0], middleCutLineLeft[1] + centerOffset[1], 1])
    middleCutLineRightBig = np.dot(M, [middleCutLineRight[0] + centerOffset[0], middleCutLineRight[1] + centerOffset[1], 1])

    # 重新将端点定位到大图上去
    upLeftBottom = np.dot(M, [upLeftBottom[0] + centerOffset[0], upLeftBottom[1] + centerOffset[1], 1])
    upRightBottom = np.dot(M, [upRightBottom[0] + centerOffset[0], upRightBottom[1] + centerOffset[1], 1])
    upLeftTop = np.dot(M, [upLeftTop[0] + centerOffset[0], upLeftTop[1] + centerOffset[1], 1])
    upRightTop = np.dot(M, [upRightTop[0] + centerOffset[0], upRightTop[1] + centerOffset[1], 1])
    downLeftTop = np.dot(M, [downLeftTop[0] + centerOffset[0], downLeftTop[1] + centerOffset[1], 1])
    downLeftBottom = np.dot(M, [downLeftBottom[0] + centerOffset[0], downLeftBottom[1] + centerOffset[1], 1])
    downRightTop = np.dot(M, [downRightTop[0] + centerOffset[0], downRightTop[1] + centerOffset[1], 1])
    downRightBottom = np.dot(M, [downRightBottom[0] + centerOffset[0], downRightBottom[1] + centerOffset[1], 1])

    # 画出内框
    cv.line(imageColor, (int(upLeftBottom[0]), int(upLeftBottom[1])), (int(upRightBottom[0]), int(upRightBottom[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(upLeftBottom[0]), int(upLeftBottom[1])), (int(upLeftTop[0]), int(upLeftTop[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(upRightBottom[0]), int(upRightBottom[1])), (int(upRightTop[0]), int(upRightTop[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(upLeftTop[0]), int(upLeftTop[1])), (int(upRightTop[0]), int(upRightTop[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(downLeftBottom[0]), int(downLeftBottom[1])), (int(downRightBottom[0]), int(downRightBottom[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(downLeftBottom[0]), int(downLeftBottom[1])), (int(downLeftTop[0]), int(downLeftTop[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(downRightBottom[0]), int(downRightBottom[1])), (int(downRightTop[0]), int(downRightTop[1])),
            colorGreen, 3)
    cv.line(imageColor, (int(downLeftTop[0]), int(downLeftTop[1])), (int(downRightTop[0]), int(downRightTop[1])),
            colorGreen, 3)

    cv.line(imageColor, (int(topCutLeftPointBig[0]), int(topCutLeftPointBig[1])),
            (int(topCutRightPointBig[0]), int(topCutRightPointBig[1])), colorRed, 3)
    cv.putText(imageColor, '1', (int((topCutLeftPointBig[0] + topCutRightPointBig[0]) / 2),
                                 int((topCutLeftPointBig[1] + topCutRightPointBig[1]) / 2) - 10),
               cv.FONT_HERSHEY_COMPLEX, 4, colorRed, 5)
    cv.line(imageColor, (int(bottomCutRightPointBig[0]), int(bottomCutRightPointBig[1])),
            (int(bottomCutLeftPointBig[0]), int(bottomCutLeftPointBig[1])), colorRed, 3)
    cv.putText(imageColor, '3', (int((bottomCutRightPointBig[0] + bottomCutLeftPointBig[0]) / 2),
                                 int((bottomCutRightPointBig[1] + bottomCutLeftPointBig[1]) / 2) + 80),
               cv.FONT_HERSHEY_COMPLEX, 4, colorRed, 5)

    cv.line(imageColor, (int(leftCutLineBottomBig[0]), int(leftCutLineBottomBig[1])),
            (int(leftCutLineTopBig[0]), int(leftCutLineTopBig[1])), colorRed, 3)
    cv.putText(imageColor, '2', (int((leftCutLineBottomBig[0] + leftCutLineTopBig[0]) / 2) - 80,
                                 int((leftCutLineBottomBig[1] + leftCutLineTopBig[1]) / 2)),
               cv.FONT_HERSHEY_COMPLEX, 4, colorRed, 5)
    cv.line(imageColor, (int(rightCutLineTopBig[0]), int(rightCutLineTopBig[1])),
            (int(rightCutLineBottomBig[0]), int(rightCutLineBottomBig[1])), colorRed, 3)
    cv.putText(imageColor, '4', (int((rightCutLineTopBig[0] + rightCutLineBottomBig[0]) / 2) + 10,
                                 int((rightCutLineTopBig[1] + rightCutLineBottomBig[1]) / 2)),
               cv.FONT_HERSHEY_COMPLEX, 4, colorRed, 5)
    cv.line(imageColor, (int(middleCutLineLeftBig[0]), int(middleCutLineLeftBig[1])),
            (int(middleCutLineRightBig[0]), int(middleCutLineRightBig[1])), colorBlue, 3)

    topCutLeftPointRobot = pix_pos_to_robot(topCutLeftPointBig, transMtx)
    topCutRightPointRobot = pix_pos_to_robot(topCutRightPointBig, transMtx)
    bottomCutLeftPointRobot = pix_pos_to_robot(bottomCutLeftPointBig, transMtx)
    bottomCutRightPointRobot = pix_pos_to_robot(bottomCutRightPointBig, transMtx)
    leftCutLineBottomRobot = pix_pos_to_robot(leftCutLineBottomBig, transMtx)
    leftCutLineTopRobot = pix_pos_to_robot(leftCutLineTopBig, transMtx)
    rightCutLineTopRobot = pix_pos_to_robot(rightCutLineTopBig, transMtx)
    rightCutLineBottomRobot = pix_pos_to_robot(rightCutLineBottomBig, transMtx)
    middleCutLineLeftRobot = pix_pos_to_robot(middleCutLineLeftBig, transMtx)
    middleCutLineRightRobot = pix_pos_to_robot(middleCutLineRightBig, transMtx)

    boardLeftTopRobot = pix_pos_to_robot(boardLeftTopBig, transMtx)
    boardRightTopRobot = pix_pos_to_robot(boardRightTopBig, transMtx)
    boardRightBottomRobot = pix_pos_to_robot(boardRightBottomBig, transMtx)
    boardLeftBottomRobot = pix_pos_to_robot(boardLeftBottomBig, transMtx)

    # 计算裁切面积和切割的长度,单位是mm
    cutDisTotal = 0
    cutAreaTotal = 0
    if topRemain != 0:
        cutDis = get_two_point_distance(topCutLeftPointRobot, topCutRightPointRobot)
        area = cutDis * (get_two_line_distance([topCutLeftPointRobot, topCutRightPointRobot], [boardLeftTopRobot, boardRightTopRobot]))
        cutDisTotal += cutDis
        cutAreaTotal += area
    if leftRemain != 0:
        cutDis = get_two_point_distance(leftCutLineBottomRobot, leftCutLineTopRobot)
        area = cutDis * (get_two_line_distance([leftCutLineTopRobot, leftCutLineBottomRobot], [boardLeftTopRobot, boardLeftBottomRobot]))
        cutDisTotal += cutDis
        cutAreaTotal += area
    if bottomRemain != 0:
        cutDis = get_two_point_distance(bottomCutLeftPointRobot, bottomCutRightPointRobot)
        area = cutDis * (get_two_line_distance([bottomCutLeftPointRobot, bottomCutRightPointRobot], [boardLeftBottomRobot, boardRightBottomRobot]))
        cutDisTotal += cutDis
        cutAreaTotal += area
    if rightRemain != 0:
        cutDis = get_two_point_distance(rightCutLineTopRobot, rightCutLineBottomRobot)
        area = cutDis * (get_two_line_distance([rightCutLineTopRobot, rightCutLineBottomRobot], [boardRightTopRobot, boardRightBottomRobot]))
        cutDisTotal += cutDis
        cutAreaTotal += area

    imageResult, _ = get_board_without_angle(imageColor, totalBoardBox, extend=80)
    image_show("ResultImage", imageResult)
    # 计算板长以及角度.
    firstBoardLength, totalBoardLength = get_board_length_2p([topCutLeftPointRobot, topCutRightPointRobot],
                                                             [middleCutLineLeftRobot, middleCutLineRightRobot],
                                                             [bottomCutLeftPointRobot, bottomCutRightPointRobot])
    # 计算角度,角度有正负,正负的问题,通过验证顺时针还有逆时针去确定.
    topMiddleAngle = get_two_line_angle([middleCutLineRightRobot, middleCutLineLeftRobot], [topCutRightPointRobot, topCutLeftPointRobot])
    bottomMiddleAngle = get_two_line_angle([middleCutLineRightRobot, middleCutLineLeftRobot], [bottomCutRightPointRobot, bottomCutLeftPointRobot])
    isFirstCut = True if topRemain != 0 else False
    isThirdCut = True if bottomRemain != 0 else False
    cutLength = [round(cutDisTotal, 5), round(cutAreaTotal, 5)]
    cutWidth = get_two_point_distance(leftCutLineTopRobot, rightCutLineTopRobot)  # 计算切割的宽度
    return [topCutLeftPointRobot, topCutRightPointRobot, bottomCutRightPointRobot, bottomCutLeftPointRobot,
            leftCutLineBottomRobot, leftCutLineTopRobot, rightCutLineTopRobot, rightCutLineBottomRobot, middleCutLineLeftRobot,
            middleCutLineRightRobot, firstBoardLength, totalBoardLength, topMiddleAngle,
            bottomMiddleAngle], imageResult, cutLength, isFirstCut, isThirdCut, cutWidth


def get_line_offset_2p(upBox, downBox, totalBoard, totalBoardBox):
    """
    获取首板的位置信息
    :param upBox:
    :param downBox:
    :param totalBoard:
    :param totalBoardBox:
    :return:
    """
    if len(totalBoard.shape) >= 3:
        totalBoard = cv.cvtColor(totalBoard, cv.COLOR_BGR2GRAY)
    w, h = totalBoardBox[1]
    heightHalf = int(h / 2)
    upBoard = totalBoard.copy()[:int(heightHalf + upDownSlice), :]
    upH, upW = upBoard.shape[:2]
    p1 = (0, 0)
    p2 = (upW, 0)
    p3 = (upW, upH)
    p4 = (0, upH)
    p5, p6, p7, p8 = upBox
    innerLine1, innerLine2, innerLine3, innerLine4 = [(p5, p6), (p6, p7), (p7, p8), (p8, p5)]
    outterLine1, outterLine2, outterLine3, outterLine4 = [(p1, p2), (p2, p3), (p3, p4), (p4, p1)]
    offsetTop = get_two_line_distance(innerLine1, outterLine1)
    offsetRight = get_two_line_distance(innerLine2, outterLine2)
    offsetBottom = get_two_line_distance(innerLine3, outterLine3)
    offsetLeft = get_two_line_distance(innerLine4, outterLine4)

    upOffset = [int(offsetTop), int(offsetRight), int(offsetBottom), int(offsetLeft)]
    # 下框的额坐标也要是totalBoard上的坐标
    p1 = (0, heightHalf - upDownSlice)
    p2 = (w, heightHalf - upDownSlice)
    p3 = (w, h)
    p4 = (0, h)
    p5, p6, p7, p8 = downBox

    innerLine1, innerLine2, innerLine3, innerLine4 = [(p5, p6), (p6, p7), (p7, p8), (p8, p5)]
    outterLine1, outterLine2, outterLine3, outterLine4 = [(p1, p2), (p2, p3), (p3, p4), (p4, p1)]
    offsetTop = get_two_line_distance(innerLine1, outterLine1)
    offsetRight = get_two_line_distance(innerLine2, outterLine2)
    offsetBottom = get_two_line_distance(innerLine3, outterLine3)
    offsetLeft = get_two_line_distance(innerLine4, outterLine4)
    downOffset = [int(offsetTop), int(offsetRight), int(offsetBottom), int(offsetLeft)]
    return upOffset, downOffset


if __name__ == '__main__':
    filePath = r"D:\2024\Yilianda"
    res, data = db.get_line_cam_check_thres()
    totalHeightMax = data.get("totalHeightMax")
    totalHeightMin = data.get("totalHeightMin")
    boardBreak = False
    calcThresBig = 20
    calcThresSmall = 9
    res1, transMtxData = db.get_trans_mtx_data()
    transMtx = None
    if res1 != "ok":
        errorInfo = "{},标定矩阵获取失败!".format(res1)
        print(errorInfo)
    else:
        transMtx = transMtxData.get("mtx")
    jointNumber = "2"
    remainEdgeMm = [11, 13, 11, 13]
    topRemain, leftRemain, bottomRemain, rightRemain = [int(x * cp.mm2pix) for x in remainEdgeMm]

    keepDir = filePath
    if not os.path.isdir(keepDir):
        keepDir, _ = os.path.split(filePath)

    keepOkPath = os.path.join(keepDir, "ok")
    keepOkResPath = os.path.join(keepDir, "cutlines")
    keepFailPath = os.path.join(keepDir, "fail")
    keepFirstSizeBestRes = os.path.join(keepDir, "first_size_check_best")

    dirList = [keepOkPath, keepOkResPath, keepFailPath, keepFirstSizeBestRes]
    for dirDemo in dirList:
        if not os.path.exists(dirDemo):
            os.mkdir(dirDemo)

    fileNames = []
    if os.path.isfile(filePath):
        filePath, fileName = os.path.split(filePath)
        fileNames.append(fileName)
    else:
        for root, dirs, files in os.walk(filePath):
            if root != filePath:
                continue
            for file in files:
                if file[-4:] != ".bmp":
                    continue
                fileNames.append(file)

    for index, fileName in enumerate(fileNames):
        filePathReal = os.path.join(filePath, fileName)
        srcW, srcH, upLineOffset, downLineOffset = get_width_height_by_image_name_2p(fileName)
        if srcW is None or srcH is None:
            print("*" * 10 + "第 {} 张图 ({}),图像名称错误,已跳过".format(index + 1, fileName))
        if 0 in upLineOffset or 0 in downLineOffset:
            isFirstBoard = True
        else:
            isFirstBoard = False

        print("*" * 10 + "第 {} 张图 ({})".format(index + 1, fileName) + "*" * 10)
        calcStart = time.time()
        imageSrc = cv.imread(filePathReal, cv.IMREAD_GRAYSCALE)
        totalBoardRes = check_total_board_is_ok(imageSrc, totalHeightMax, totalHeightMin, boardBreak, jointNumber)
        res, hintInfo, totalBoardBox, totalBoardNoAngle, totalBoardOffset, totalBoardThresWithAngle, totalBoardResWithAngle = totalBoardRes
        print("物料检测结果: {}, {}".format(res, hintInfo))
        if isFirstBoard:
            resFirst, boardSizeList, boardResList, upBoard = get_size_check_result_2p(imageSrc, srcW, srcH, calcThresBig, totalBoardBox,
                                                                                      totalBoardNoAngle)
            if resFirst != "error":
                sizeCheckResBest = boardResList[0]
                sizeCheckResBest = get_size_scale_image(sizeCheckResBest, sizeScale=4)
                cv.imwrite(os.path.join(keepFirstSizeBestRes, fileName), sizeCheckResBest)

        res, info, upBox, downBox = get_boxes_2pin(imageSrc, srcW, srcH, calcThresBig, calcThresSmall, totalBoardBox, totalBoardNoAngle,
                                                upLineOffset, downLineOffset, isFirstBoard)
        if res:
            lineRes = get_lines_with_boxes_2p(imageSrc, totalBoardNoAngle, totalBoardBox, totalBoardThresWithAngle, upBox, downBox, transMtx,
                                              topRemain, leftRemain, bottomRemain, rightRemain, totalBoardOffset)
            cutLines, imageRes, cutDis, isFirstCut, isThirdCut, cutWidth = lineRes
            print("算法耗时: {}".format(time.time() - calcStart))
            os.remove(filePathReal)
            imageRes = get_size_scale_image(imageRes, sizeScale=4)
            cv.imwrite(os.path.join(keepOkResPath, fileName), imageRes)
            cv.imwrite(os.path.join(keepOkPath, fileName), imageSrc)
            print("识别成功!结果:切割面积:{},切割宽度:{},角度长度:{}".format(cutDis, cutWidth, cutLines[-4:]))
            continue
        else:
            print("算法耗时: {}".format(time.time() - calcStart))
            cv.imwrite(os.path.join(keepFailPath, fileName), imageSrc)
            os.remove(filePathReal)
            print("识别失败XXXXXXXXXXXXXXXXXXXXXXXXX")
            continue
